﻿#ifndef Reflection_h__2013_8_27__21_58
#define Reflection_h__2013_8_27__21_58

//编译期反射


//初始化元数据
#define META_DATA_INIT	\
	template<int T>	\
struct Meta_Data_Container;	\
	\
	static const int _member_Begin_Index = __COUNTER__ + 1;	\
	\
	template<int Index>	\
	auto Get_Member() -> typename Meta_Data_Container<Index + _member_Begin_Index>::type &;	\
	\
	template<int Index>	\
struct Get_Member_Type;	\
	\
	template<int Index>	\
	static df::CC Get_Member_Name();	\
	typedef Meta_Data_Container<0> Meta_Data;


//添加成员元数据(成员所属类名,成员名,扩展信息)
#define META_DATA_MEMBER_EXTRA(C_NAME,M_NAME,M_EXTRA)	\
	template<>	\
struct C_NAME::Meta_Data_Container<__COUNTER__>	\
{	\
	typedef decltype(((C_NAME*)0)->M_NAME) type;	\
	static type & Member(C_NAME & obj)	\
	{	\
	return obj.M_NAME;	\
	}	\
	static df::CC Name()	\
	{	\
	return tcc_(DF_NAME_VALUE(M_NAME));	\
	}	\
	M_EXTRA \
};

//普通成员
#define META_DATA_MEMBER(C_NAME , M_NAME) META_DATA_MEMBER_EXTRA(C_NAME , M_NAME , )

//复合成员
#define META_DATA_MEMBER_COMP(C_NAME , M_NAME) META_DATA_MEMBER_EXTRA(C_NAME , M_NAME,	\
	typedef int compositionType;)

//vector成员
#define META_DATA_MEMBER_VECTOR(C_NAME , M_NAME) META_DATA_MEMBER_EXTRA(C_NAME , M_NAME,	\
	typedef int vectorType;)


//添加结束(类名)
#define META_DATA_END(C_NAME)	\
	template<>	\
struct C_NAME::Meta_Data_Container<0>	\
{	\
	static const int _member_End_Index = __COUNTER__;	\
	static const int member_Size = _member_End_Index - C_NAME::_member_Begin_Index;	\
	typedef df::EnumMetaMember <C_NAME, member_Size - 1> EachMember;	\
};	\
	\
	template<int Index>	\
	auto C_NAME::Get_Member() -> typename Meta_Data_Container<Index + _member_Begin_Index>::type &	\
{	\
	static_assert(Index >= 0 && Index < Meta_Data::member_Size, "Index out of range");	\
	return Meta_Data_Container<Index + _member_Begin_Index>::Member(*this);	\
}	\
	\
	template<int Index>	\
struct C_NAME::Get_Member_Type	\
{	\
	static_assert(Index >= 0 && Index < Meta_Data::member_Size, "Index out of range");	\
	typedef typename Meta_Data_Container<Index + _member_Begin_Index>::type type;	\
	typedef Meta_Data_Container<Index + _member_Begin_Index> container;	\
};	\
	\
	template<int Index>	\
	df::CC C_NAME::Get_Member_Name()	\
{	\
	static_assert(Index >= 0 && Index < Meta_Data::member_Size, "Index out of range");	\
	return Meta_Data_Container<Index + _member_Begin_Index>::Name();	\
}


#define  META_DATA_MEMBER_1(C_NAME,_1) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_2(C_NAME, _1, _2) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_3(C_NAME, _1, _2, _3) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_4(C_NAME, _1, _2, _3, _4) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_MEMBER(C_NAME, _4); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_5(C_NAME, _1, _2, _3, _4, _5) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_MEMBER(C_NAME, _4); \
	META_DATA_MEMBER(C_NAME, _5); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_6(C_NAME, _1, _2, _3, _4, _5, _6) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_MEMBER(C_NAME, _4); \
	META_DATA_MEMBER(C_NAME, _5); \
	META_DATA_MEMBER(C_NAME, _6); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_7(C_NAME, _1, _2, _3, _4, _5, _6, _7) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_MEMBER(C_NAME, _4); \
	META_DATA_MEMBER(C_NAME, _5); \
	META_DATA_MEMBER(C_NAME, _6); \
	META_DATA_MEMBER(C_NAME, _7); \
	META_DATA_END(C_NAME)

#define  META_DATA_MEMBER_8(C_NAME, _1, _2, _3, _4, _5, _6, _7, _8) \
	META_DATA_MEMBER(C_NAME, _1); \
	META_DATA_MEMBER(C_NAME, _2); \
	META_DATA_MEMBER(C_NAME, _3); \
	META_DATA_MEMBER(C_NAME, _4); \
	META_DATA_MEMBER(C_NAME, _5); \
	META_DATA_MEMBER(C_NAME, _6); \
	META_DATA_MEMBER(C_NAME, _7); \
	META_DATA_MEMBER(C_NAME, _8); \
	META_DATA_END(C_NAME)

namespace df
{
	//遍历类型所有成员
	//MetaT 待遍历的类型
	//I 索引,倒序遍历正序输出,从Meta_Data::member_Size-1开始至-1结束
	template<class MetaT, int I = MetaT::Meta_Data::member_Size - 1>
	struct EnumMetaMember
	{
		///FuncT:仿函数回调(template<int> void())
		template<typename FuncT>
		static void Start(FuncT && cb)
		{
			EnumMetaMember<MetaT, I - 1>::Start(cb);

			cb.DF_TEMPLATE operator()<I>();
		}

	};
	template<class MetaT>
	struct EnumMetaMember<MetaT, -1>
	{
		template<typename FuncT>
		static void Start(FuncT &&)
		{

		}
	};

	template<class OT>
	struct InitAssignFunc;

	//对象赋值函数表(String to object)
	typedef void(*AssignStrFunc)(void *, const df::CC &);
	typedef std::map <df::CC, AssignStrFunc> AssignFuncMap;

	//复合成员函数
	typedef void * (*CompositionMemberFunc)(void *, AssignFuncMap* &, void * &);
	//复合成员函数表
	typedef std::map < df::CC, CompositionMemberFunc> CompositionMemberFuncMap;

	template<class T>
	struct Reflection
	{
	private:
		struct No  { char a[1]; };
		struct Yes { char a[2]; };

		template<class C>
		static No Test(...);

		template<class C>
		static Yes Test(typename C::Meta_Data *);


	public:
		//判断对象是否包含元数据
		enum
		{
			Support = sizeof(Test<T>(0)) == sizeof(Yes)
		};

		//获取赋值函数表
		static AssignFuncMap & GetAssignFuncMap()
		{
			static_assert(Support, "Object does not support Reflection (need META_DATA_INIT)");

			static AssignFuncMap funcMap;

			static bool uninitialized = true;
			if (uninitialized)
			{
				EnumMetaMember<T>::Start(InitAssignFunc<T>({ funcMap }));
				uninitialized = false;
			}

			return funcMap;
		}


		//*******************************************
		// Summary : 向obj对象的指定下标I成员赋值字串val
		// Parameter - void * obj : 赋值对象
		// Parameter - const df::CC & val : 字串
		//*******************************************
		template<int I>
		static void Assignment(void * obj, const df::CC & val)
		{
			StrToVar(val, static_cast<T*>(obj)->DF_TEMPLATE Get_Member<I>());
		}




		//*******************************************
		// Summary : 获取对象复合成员指针,复合成员赋值函数表,复合成员的复合成员函数表
		// Parameter - void * obj : 对象指针
		// Parameter - AssignFuncMap & out : 成员赋值函数表
		// Parameter - void *  & memOut : 复合成员指针
		// Returns - void * : 复合成员的复合成员函数表
		//*******************************************
		template<int I>
		static void * MemberMap(void * obj, AssignFuncMap* & out, void* & memOut)
		{
			out =& df::Reflection<typename T::template Get_Member_Type<I>::type>::GetAssignFuncMap();
		
			memOut = &(static_cast<T*>(obj)->DF_TEMPLATE Get_Member<I>());
			return &(df::Reflection<typename T::template Get_Member_Type<I>::type>::GetCompositionMemberFuncMap());
		}



		static CompositionMemberFuncMap & GetCompositionMemberFuncMap()
		{
			static CompositionMemberFuncMap mm;
			return mm;
		}

	};


	///初始化赋值函数表
	template<class OT>
	struct InitAssignFunc
	{
		AssignFuncMap & map_;

		//复合成员
		template<int I, class MT>
		void Assign(typename MT::template Get_Member_Type<I>::container::compositionType)
		{
			//typedef typename MT::template Get_Member_Type<I>::type SubType;
			Reflection<OT>::GetCompositionMemberFuncMap()[OT::template Get_Member_Name<I>()] = Reflection<OT>::DF_TEMPLATE MemberMap<I>;
		}

		//普通成员
		template<int I, class MT>
		void Assign(...)
		{
			map_[OT::template Get_Member_Name<I>()] = Reflection<OT>::DF_TEMPLATE Assignment<I>;
		}


		template<int I>
		void operator()()
		{
			Assign<I, OT>(1);
		}
	};

}



#endif // Reflection_h__2013_8_27__21_58
